package com.abl.core.common.security;


import com.abl.core.common.properties.SecurityPro;
import com.abl.core.common.util.AuthKit;
import com.abl.core.common.util.JwtKit;
import com.abl.core.domain.project.MSG;
import com.abl.core.domain.project.ServiceException;
import com.abl.core.service.sys.SysRoleService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;

/**
 * 权限拦截
 *
 * @author 王永吉
 */
@Slf4j
@Component
public class AuthInterceptor implements HandlerInterceptor {

    @Resource
    private SecurityPro securityProperties;
    @Resource
    private SysRoleService sysRoleService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Headers", "authorization,Authorization,Token,Auth,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type");

        //放行OPTIONS
        String method = request.getMethod();
        if (method.equals("OPTIONS")) return true;
        String requestURI = request.getRequestURI();

        //放行资源：匹配放行路径,从缓存中读取，初始化数据从配置文件中来
        boolean matches = checkIgnoreUrl(requestURI);
        if (matches) return true;

        //检查Token
        String token = request.getHeader("Token");
        if (token == null) throw new ServiceException(MSG.NOT_TOKEN);
        JwtKit.check(token);

        //获取用户信息，判断角色是否具备 URL访问资格.
        AuthUser currentUser = AuthKit.getCurrentUser(token);
        if (currentUser == null) throw new ServiceException(MSG.ER_410);
        //超级用户放行
        if (currentUser.isRoot()) return true;
        boolean hasRes = sysRoleService.checkHasRes(requestURI, currentUser);
        if (hasRes) return true;

        //权限不足
        throw new ServiceException(MSG.ER_403);
    }


    /**
     * 匹配放行URI
     */
    private boolean checkIgnoreUrl(String requestURI) {
        List<String> ignoreUrls = securityProperties.getIgnoreUrls();
        log.error(" ignoreUrls {}", ignoreUrls);

        AntPathMatcher pathMatcher = new AntPathMatcher();

        for (String ignoreUrl : ignoreUrls) {
            boolean match = pathMatcher.match(ignoreUrl, requestURI);
            if (match) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception exception) {
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView modelAndView) {
    }

}
